/*
01背包问题
有N件物品和一个容量是V的背包。每件物品只能使用一次。
第i件物品的体积是vi，价值是wi。
求解将哪些物品装入背包，可使这些物品的总体积不超过背包容量，且总价值最大。
输出最大价值。

输入格式
第一行两个整数，N.V，用空格隔开，分别表示物品数量和背包容积。
接下来有N行，每行两个整数vi，wi，用空格隔开，分别表示第i件物品的体积和价值。

输出格式
输出一个整数，表示最大价值。

数据范围
0<N, V ≤ 1000
0< vi, wi ≤ 1000

输入样例
4 5
1 2
2 4
3 4
4 5

输出样例
8
 */

//import java.util.*;
//
//public class Main {
//    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        int n = sc.nextInt();
//        int v = sc.nextInt();
//        int[] dp = new int[v + 1];
//        int[] volume = new int[n + 1];
//        int[] weight = new int[n + 1];
//        for (int i = 1; i <= n; i++) {
//            volume[i] = sc.nextInt();
//            weight[i] = sc.nextInt();
//        }
//        for (int i = 1; i <= n; i++) {
//            for (int j = v; j >= volume[i]; j--) {
//                dp[j] = Math.max(dp[j], dp[j - volume[i]] + weight[i]);
//            }
//        }
//        System.out.println(dp[v]);
//    }
//}

/*
完全背包问题
有N种物品和一个容量是V的背包，每种物品都有无限件可用。
第i种物品的体积是vi，价值是wi。
求解将哪些物品装入背包，可使这些物品的总体积不超过背包容量，且总价值最大。
输出最大价值。

输入格式
第一行两个整数，N，V，用空格隔开，分别表示物品种数和背包容积。
接下来有N行，每行两个整数，表示最大价值。

输出格式
输出一个整数，表示最大价值。

数据范围
0<n,V≤1000
0<vi,Wi≤1000

输入样例
4 5
1 2
2 4
3 4
4 5

输出样例：
10
 */
//import java.util.*;
//
//public class Main {
//    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        int N = sc.nextInt(); // 物品种类数
//        int V = sc.nextInt(); // 背包容量
//        int[] v = new int[N + 1]; // 每种物品的体积
//        int[] w = new int[N + 1]; // 每种物品的价值
//
//        for (int i = 1; i <= N; i++) {
//            v[i] = sc.nextInt();
//            w[i] = sc.nextInt();
//        }
//
//        // 定义 dp 数组，dp[j] 表示容量为 j 时的最大价值
//        int[] dp = new int[V + 1];
//
//        // 动态规划求解完全背包问题
//        for (int i = 1; i <= N; i++) {
//            for (int j = v[i]; j <= V; j++) { // 注意这里是正序遍历
//                dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
//            }
//        }
//
//        // 输出结果
//        System.out.println(dp[V]);
//    }
//}

/*
多重背包问题I
有 N种物品和一个容量是 V的背包。
第 i种物品最多有 si件，每件体积是 vi，价值是 wi。
求解将哪些物品装入背包，可使物品体积总和不超过背包容量，且价值总和最大。
输出最大价值。

输入格式
第一行两个整数，N，V，用空格隔开，分别表示物品种数和背包容积。
接下来有 N行，每行三个整数 vi,wi,si，用空格隔开，分别表示第 i种物品的体积、价值和数量。

输出格式
输出一个整数，表示最大价值。

数据范围
0<N,V≤100
0<vi,wi,si≤100

输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例：
10
 */

//import java.util.*;
//public class Main {
//    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        int N = sc.nextInt(), V = sc.nextInt();
//        int[] v = new int[105];
//        int[] w = new int[105];
//        int[] s = new int[105];
//        for (int i = 1; i <= N; i++) {
//            v[i] = sc.nextInt();
//            w[i] = sc.nextInt();
//            s[i] = sc.nextInt();
//        }
//        int[][] dp = new int[105][105];
//        for (int i = 1; i <= N; i++) {
//            for (int j = 1; j <= V; j++) {
//                for (int k = 0; k <= s[i] && j - v[i] * k >= 0; k++) {
//                    dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v[i] * k] + w[i] * k);
//                }
//            }
//        }
//        System.out.println(dp[N][V]);
//    }
//}

/*
多重背包问题II
有 N种物品和一个容量是 V的背包。
第 i种物品最多有 si件，每件体积是 vi，价值是 wi。
求解将哪些物品装入背包，可使物品体积总和不超过背包容量，且价值总和最大。
输出最大价值。

输入格式
第一行两个整数，N，V，用空格隔开，分别表示物品种数和背包容积。
接下来有 N行，每行三个整数 vi,wi,si，用空格隔开，分别表示第 i种物品的体积、价值和数量。

输出格式
输出一个整数，表示最大价值。

数据范围
0<N≤1000
0<V≤2000
0<vi,wi,si≤2000

输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例：
10
 */
// 多重背包问题  二进制优化版本

//import java.util.*;
//
//public class Main {
//    public static void main(String[] args) {
//        Scanner sc = new Scanner(System.in);
//        int N = sc.nextInt(), V = sc.nextInt();
//        int[] v = new int[12010];
//        int[] w = new int[12010];
//        int[] dp = new int[4010];
//        int idx = 0;
//        for (int i = 1; i <= N; i++) {
//            int a = sc.nextInt();
//            int b = sc.nextInt();
//            int s = sc.nextInt();
//            int k = 1;
//            while (k <= s) {
//                ++idx;
//                v[idx] = a * k;
//                w[idx] = b * k;
//                s -= k;
//                k *= 2;
//            }
//            if (s > 0) {
//                ++idx;
//                v[idx] = a * s;
//                w[idx] = b * s;
//            }
//        }
//
//        for (int i = 1; i <= idx; i++) {
//            for (int j = V; j >= v[i]; j--) {
//                dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
//            }
//        }
//        System.out.println(dp[V]);
//    }
//}


//分组背包问题 题干见 https://www.acwing.com/problem/content/9/
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int V = sc.nextInt();
        int[][] v = new int[200][500];
        int[][] w = new int[200][500];
        int[] s = new int[200];
        for (int i = 1; i <= N; i++) {
            s[i] = sc.nextInt();
            for (int j = 1; j <= s[i]; j++) {
                v[i][j] = sc.nextInt();
                w[i][j] = sc.nextInt();
            }
        }
        int[][] dp = new int[N + 1][500];
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= V; j++) {
                dp[i][j] = dp[i - 1][j];
                for (int k = 1; k <= s[i]; k++) {
                    if (j >= v[i][k]) dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - v[i][k]] + w[i][k]);
                }
            }
        }
        System.out.println(dp[N][V]);

    }
}